/**
 * 
 */
package com.nari.baseinfo.dao;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.Criteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

import com.nari.baseinfo.model.IConcentrator;
import com.nari.coreframe.dao.hibernate3.GenericDaoImpl;
import com.nari.platform.model.PageCond;
import com.nari.platform.model.ResponseMsg;
import com.nari.platform.model.ResultWithPageCond;
import com.nari.platform.utils.StringUtils;
import com.nari.rescontroller.dao.IResourceAccessControlDao;

/**
 * 
 * @author Xiaopeng
 * @date 2013-8-1
 */
public class ConcentratorDaoImpl extends GenericDaoImpl<IConcentrator, String> 
		implements IConcentratorDao {
	private IResourceAccessControlDao iResourceAccessControlDao;
	
	/**
	 * 分页查询集中器信息
	 * @param projectUID 所属项目ID(可选)
	 * @param communityUID 所属小区ID(可选)
	 * @param concentratorNo 集中器号(可选)
	 * @param pageCond
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-8-15
	 */
	@SuppressWarnings("unchecked")
	public ResultWithPageCond<IConcentrator> queryConcentratorPage(String projectUID, 
			String communityUID, String concentratorNo, PageCond pageCond) throws Exception {
		Criteria listCriteria = this.getCurrentSession().createCriteria(IConcentrator.class);
		Criteria countCriteria = this.getCurrentSession().createCriteria(IConcentrator.class);
		//所属项目
		if(projectUID!=null && !"".equals(projectUID.trim())) {
			listCriteria.add(Restrictions.eq("projectID", projectUID.trim()));
			countCriteria.add(Restrictions.eq("projectID", projectUID.trim()));
		}
		//所属小区
		if(communityUID!=null && !"".equals(communityUID.trim())) {
			listCriteria.add(Restrictions.eq("communityID", communityUID.trim()));
			countCriteria.add(Restrictions.eq("communityID", communityUID.trim()));
		}
		//集中器号
		if(concentratorNo!=null && !"".equals(concentratorNo.trim())) {
			listCriteria.add(Restrictions.ilike("concentratorNo", concentratorNo.trim().toLowerCase(), MatchMode.ANYWHERE));
			countCriteria.add(Restrictions.ilike("concentratorNo", concentratorNo.trim().toLowerCase(), MatchMode.ANYWHERE));
		}
		//权限资源匹配
		String authorityRes = iResourceAccessControlDao.queryAuthorityProjResSql();
		if(!"".equals(authorityRes)) {
			//这是一个直接与底层数据库耦合的查询，注意避免数模更改带来的系统问题
			listCriteria.add(Restrictions.sqlRestriction("{alias}.t_project_id in("+authorityRes+")"));
			countCriteria.add(Restrictions.sqlRestriction("{alias}.t_project_id in("+authorityRes+")"));
		}
		//统计结果集个数
		int total = ((Long)countCriteria.setProjection(Projections.rowCount()).list().get(0)).intValue();
		//结果集排序
		listCriteria.addOrder(Order.asc("concentratorNo"));
		//结果集分页
		listCriteria.setFirstResult(pageCond.getStart()).setMaxResults(pageCond.getLimit());
		//构造返回类型
		pageCond.setTotal(total);
		ResultWithPageCond<IConcentrator> concentratorPage = new ResultWithPageCond<IConcentrator>();
		concentratorPage.setList(listCriteria.list());
		concentratorPage.setPageCond(pageCond);
		return concentratorPage;
	}
	
	/**
	 * 分页查询集中器信息
	 * @param projectUID 所属项目ID(可选)
	 * @param communityUID 所属小区ID(可选)
	 * @param buildingUID 所属楼栋ID(可选)
	 * @param concentratorNo 集中器号(可选)
	 * @param pageCond
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-8-15
	 */
	@Override
	public ResultWithPageCond<IConcentrator> queryConcentratorPage(String projectUID, 
			String communityUID, String buildingUID,String  concentratorNo, PageCond pageCond) throws Exception {
		Criteria listCriteria = this.getCurrentSession().createCriteria(IConcentrator.class);
		Criteria countCriteria = this.getCurrentSession().createCriteria(IConcentrator.class);
		//所属项目
		if(projectUID!=null && !"".equals(projectUID.trim())) {
			listCriteria.add(Restrictions.eq("projectID", projectUID.trim()));
			countCriteria.add(Restrictions.eq("projectID", projectUID.trim()));
		}
		//所属小区
		if(communityUID!=null && !"".equals(communityUID.trim())) {
			listCriteria.add(Restrictions.eq("communityID", communityUID.trim()));
			countCriteria.add(Restrictions.eq("communityID", communityUID.trim()));
		}
		//所属楼栋
		if(buildingUID!=null && !"".equals(buildingUID.trim())) {
			listCriteria.add(Restrictions.eq("buildingID", buildingUID.trim()));
			countCriteria.add(Restrictions.eq("buildingID", buildingUID.trim()));
		}
		//集中器号
		if(concentratorNo!=null && !"".equals(concentratorNo.trim())) {
			listCriteria.add(Restrictions.ilike("concentratorNo", concentratorNo.trim().toLowerCase(), MatchMode.ANYWHERE));
			countCriteria.add(Restrictions.ilike("concentratorNo", concentratorNo.trim().toLowerCase(), MatchMode.ANYWHERE));
		}
		//权限资源匹配
		String authorityRes = iResourceAccessControlDao.queryAuthorityProjResSql();
		if(!"".equals(authorityRes)) {
			//这是一个直接与底层数据库耦合的查询，注意避免数模更改带来的系统问题
			listCriteria.add(Restrictions.sqlRestriction("{alias}.t_project_id in("+authorityRes+")"));
			countCriteria.add(Restrictions.sqlRestriction("{alias}.t_project_id in("+authorityRes+")"));
		}
		//统计结果集个数
		int total = ((Long)countCriteria.setProjection(Projections.rowCount()).list().get(0)).intValue();
		//结果集排序
		listCriteria.addOrder(Order.asc("concentratorNo"));
		//结果集分页
		listCriteria.setFirstResult(pageCond.getStart()).setMaxResults(pageCond.getLimit());
		//构造返回类型
		pageCond.setTotal(total);
		ResultWithPageCond<IConcentrator> concentratorPage = new ResultWithPageCond<IConcentrator>();
		concentratorPage.setList(listCriteria.list());
		concentratorPage.setPageCond(pageCond);
		return concentratorPage;
	}
	
	
	/**
	 * 通过集中器所属关系（所属项目、所属小区、所属分摊域）查询集中器列表
	 * 若所属关系均不存在，则返回空列表
	 * @param projectUID 所属项目
	 * @param communityUID 所属小区
	 * @param shareAreaUID 所属分摊域
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-8-27
	 */
	@SuppressWarnings("unchecked")
	public List<IConcentrator> queryConcentratorsByBelongs(String projectUID, 
			String communityUID, String shareAreaUID) throws Exception {
		Criteria listCriteria = this.getCurrentSession().createCriteria(IConcentrator.class);
		if((projectUID!=null && !"".equals(projectUID)) 
				|| (communityUID!=null && !"".equals(communityUID)) 
				|| (shareAreaUID!=null && !"".equals(shareAreaUID))) {
			//所属项目
			if(projectUID!=null && !"".equals(projectUID.trim())) {
				listCriteria.add(Restrictions.eq("projectID", projectUID.trim()));
			}
			//所属小区
			if(communityUID!=null && !"".equals(communityUID.trim())) {
				listCriteria.add(Restrictions.eq("communityID", communityUID.trim()));
			}
			//所属分摊域
			if(shareAreaUID!=null && !"".equals(shareAreaUID.trim())) {
				listCriteria.add(Restrictions.eq("shareAreaUID", shareAreaUID.trim()));
			}
			//权限资源匹配
			String authorityRes = iResourceAccessControlDao.queryAuthorityProjResSql();
			if(!"".equals(authorityRes)) {
				//这是一个直接与底层数据库耦合的查询，注意避免数模更改带来的系统问题
				listCriteria.add(Restrictions.sqlRestriction("{alias}.t_project_id in("+authorityRes+")"));
			}
			//结果集排序
			listCriteria.addOrder(Order.asc("concentratorNo"));
			return listCriteria.list();
		}
		return new ArrayList<IConcentrator>();
	}
	
	/**
	 * 通过集中器ID列表查询集中器ID-集中器号concentratorNo映射表
	 * @param idList 集中器ID列表，若列表为空，则返回一个空映射表
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-8-29
	 */
	public Map<String, String> queryIdNameMapByIDList(List<String> idList) throws Exception {
		Map<String, String> idNameMap = new HashMap<String, String>();
		if(idList!=null && idList.size()>0) {
			StringBuffer hsql = new StringBuffer("select distinct c.id,c.concentratorNo ");
			hsql.append("from IConcentrator c ");
			hsql.append("where c.id in(");
			for(int index=0; index<idList.size(); index++) {
				hsql.append("'");
				hsql.append(idList.get(index));
				hsql.append("'");
				if(index < idList.size()-1) {
					hsql.append(",");
				}
			}
			hsql.append(")");
			List<Object> resultsList = this.runQueryHSqlObject(hsql.toString());
			//格式化查询结果集
			if(resultsList!=null && resultsList.size()>0) {
				for(Object result: resultsList) {
					Object[] arrayMap = (Object[]) result;
					idNameMap.put(arrayMap[0].toString(), arrayMap[1].toString());
				}
			}
		}
		return idNameMap;
	}
	
	/**
	 * 通过集中器号查询集中器实体
	 * @param concentratorNo
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-9-2
	 */
	public IConcentrator queryByConcentratorNo(String concentratorNo) throws Exception {
		String hsql = "from IConcentrator c " +
				"where trim(c.concentratorNo)='"+concentratorNo.trim()+"'";
		List<IConcentrator> concentratorList = this.runQueryHSql(hsql);
		IConcentrator concentrator = null;
		if(concentratorList!=null && concentratorList.size()>0) {
			concentrator = concentratorList.get(0);
		}
		return concentrator;
	}
	
	/**
	 * 根据所属分摊域信息查询集中器信息
	 * @param shareAreaUID 所属分摊域(必选)
	 * 说明：若分摊域ID不存在，则返回零结果集
	 * @param projectUID 所属项目(可选)
	 * @param communityUID 所属小区(可选)
	 * @param concentratorNo 集中器号(可选)
	 * @param pageCond
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-9-3
	 */
	@SuppressWarnings("unchecked")
	public ResultWithPageCond<IConcentrator> queryConcentratorPageByAreaUID(String shareAreaUID, 
			String projectUID, String communityUID, String concentratorNo, 
			PageCond pageCond) throws Exception {
		List<IConcentrator> concentratorList = new ArrayList<IConcentrator>();
		int total = 0;
		//分摊域存在时，分页查询集中器列表
		if(shareAreaUID!=null && !"".equals(shareAreaUID.trim())) {
			Criteria listCriteria = this.getCurrentSession().createCriteria(IConcentrator.class);
			Criteria countCriteria = this.getCurrentSession().createCriteria(IConcentrator.class);
			//所属分摊域
			listCriteria.add(Restrictions.eq("shareAreaID", shareAreaUID.trim()));
			countCriteria.add(Restrictions.eq("shareAreaID", shareAreaUID.trim()));
			//所属项目
			if(projectUID!=null && !"".equals(projectUID.trim())) {
				listCriteria.add(Restrictions.eq("projectID", projectUID.trim()));
				countCriteria.add(Restrictions.eq("projectID", projectUID.trim()));
			}
			//所属小区
			if(communityUID!=null && !"".equals(communityUID.trim())) {
				listCriteria.add(Restrictions.eq("communityID", communityUID.trim()));
				countCriteria.add(Restrictions.eq("communityID", communityUID.trim()));
			}
			//集中器号
			if(concentratorNo!=null && !"".equals(concentratorNo.trim())) {
				listCriteria.add(Restrictions.ilike("concentratorNo", concentratorNo.trim().toLowerCase(), MatchMode.ANYWHERE));
				countCriteria.add(Restrictions.ilike("concentratorNo", concentratorNo.trim().toLowerCase(), MatchMode.ANYWHERE));
			}
			//权限资源匹配
			String authorityRes = iResourceAccessControlDao.queryAuthorityProjResSql();
			if(!"".equals(authorityRes)) {
				//这是一个直接与底层数据库耦合的查询，注意避免数模更改带来的系统问题
				listCriteria.add(Restrictions.sqlRestriction("{alias}.t_project_id in("+authorityRes+")"));
				countCriteria.add(Restrictions.sqlRestriction("{alias}.t_project_id in("+authorityRes+")"));
			}
			//统计结果集个数
			total = ((Long)countCriteria.setProjection(Projections.rowCount()).list().get(0)).intValue();
			//结果集排序
			listCriteria.addOrder(Order.asc("concentratorNo"));
			//结果集分页
			listCriteria.setFirstResult(pageCond.getStart()).setMaxResults(pageCond.getLimit());
			concentratorList = listCriteria.list();
		}
		//构造返回类型
		pageCond.setTotal(total);
		ResultWithPageCond<IConcentrator> concentratorPage = new ResultWithPageCond<IConcentrator>();
		concentratorPage.setList(concentratorList);
		concentratorPage.setPageCond(pageCond);
		return concentratorPage;
	}
	
	/**
	 * 查询不隶属于某个分摊域下的集中器列表
	 * @param shareAreaUID 所属分摊域(必选)
	 * 说明：若分摊域ID不存在，则返回零结果集
	 * @param projectUID 所属项目(可选)
	 * @param communityUID 所属小区(可选)
	 * @param concentratorNo 集中器号(可选)
	 * @param pageCond
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-9-3
	 */
	@SuppressWarnings("unchecked")
	public ResultWithPageCond<IConcentrator> queryConcentratorPageExceptAreaUID(String shareAreaUID, 
			String projectUID, String communityUID, String concentratorNo, 
			PageCond pageCond) throws Exception {
		List<IConcentrator> concentratorList = new ArrayList<IConcentrator>();
		int total = 0;
		//分摊域存在时，分页查询集中器列表
		if(shareAreaUID!=null && !"".equals(shareAreaUID.trim())) {
			Criteria listCriteria = this.getCurrentSession().createCriteria(IConcentrator.class);
			Criteria countCriteria = this.getCurrentSession().createCriteria(IConcentrator.class);
			//不隶属于某个分摊域
			listCriteria.add(Restrictions.or(Restrictions.isNull("shareAreaID"), Restrictions.eq("shareAreaID", "")));
			countCriteria.add(Restrictions.or(Restrictions.isNull("shareAreaID"), Restrictions.eq("shareAreaID", "")));
			//所属项目
			if(projectUID!=null && !"".equals(projectUID.trim())) {
				listCriteria.add(Restrictions.eq("projectID", projectUID.trim()));
				countCriteria.add(Restrictions.eq("projectID", projectUID.trim()));
			}
			//所属小区
			if(communityUID!=null && !"".equals(communityUID.trim())) {
				listCriteria.add(Restrictions.eq("communityID", communityUID.trim()));
				countCriteria.add(Restrictions.eq("communityID", communityUID.trim()));
			}
			//集中器号
			if(concentratorNo!=null && !"".equals(concentratorNo.trim())) {
				listCriteria.add(Restrictions.ilike("concentratorNo", concentratorNo.trim().toLowerCase(), MatchMode.ANYWHERE));
				countCriteria.add(Restrictions.ilike("concentratorNo", concentratorNo.trim().toLowerCase(), MatchMode.ANYWHERE));
			}
			//权限资源匹配
			String authorityRes = iResourceAccessControlDao.queryAuthorityProjResSql();
			if(!"".equals(authorityRes)) {
				//这是一个直接与底层数据库耦合的查询，注意避免数模更改带来的系统问题
				listCriteria.add(Restrictions.sqlRestriction("{alias}.t_project_id in("+authorityRes+")"));
				countCriteria.add(Restrictions.sqlRestriction("{alias}.t_project_id in("+authorityRes+")"));
			}
			//统计结果集个数
			total = ((Long)countCriteria.setProjection(Projections.rowCount()).list().get(0)).intValue();
			//结果集排序
			listCriteria.addOrder(Order.asc("concentratorNo"));
			//结果集分页
			listCriteria.setFirstResult(pageCond.getStart()).setMaxResults(pageCond.getLimit());
			concentratorList = listCriteria.list();
		}
		//构造返回类型
		pageCond.setTotal(total);
		ResultWithPageCond<IConcentrator> concentratorPage = new ResultWithPageCond<IConcentrator>();
		concentratorPage.setList(concentratorList);
		concentratorPage.setPageCond(pageCond);
		return concentratorPage;
	}
	
	/**
	 * 批量设置集中器所属分摊域信息
	 * @param shareAreaUID 所属分摊域
	 * @param concentratorIDList 集中器ID列表，格式：XXX,XXX,XXX
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-9-3
	 */
	public ResponseMsg saveConcentratorArea(String shareAreaUID, 
			String concentratorIDList) throws Exception {
		String formatConcentratorIDList = StringUtils.formatIDListWithSyntax(concentratorIDList, ",", "'");
		String updateHql = "update IConcentrator c " +
				"set c.shareAreaID='"+shareAreaUID+"' " +
				"where c.id in("+formatConcentratorIDList+")";
		this.runFormatHSql(updateHql);
		return ResponseMsg.getInstance(true, "");
	}
	
	/**
	 * 将存储格式的上传周期格式化为数值型的上传周期
	 * @param uploadCycle
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-9-23
	 */
	public int formatUploadCycle(String uploadCycle) throws Exception {
		int formatUploadCycle = 0; //默认为0，即不符合规定的上传周期
		if("perday".equals(uploadCycle)) {
			formatUploadCycle = 1;
		}
		if("per3day".equals(uploadCycle)) {
			formatUploadCycle = 3;
		}
		if("per7day".equals(uploadCycle)) {
			formatUploadCycle = 7;
		}
		if("per15day".equals(uploadCycle)) {
			formatUploadCycle = 15;
		}
		if("permonth".equals(uploadCycle)) {
			formatUploadCycle = 30;
		}
		return formatUploadCycle;
	}
	
	/**
	 * 通过集中器所属信息统计集中器的个数
	 * @param projectUID
	 * @param communityUID
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-10-23
	 */
	public int countConcentratorSumByBelongs(String projectUID, 
			String communityUID) throws Exception {
		Criteria countCriteria = this.getCurrentSession().createCriteria(IConcentrator.class);
		//所属项目
		if(projectUID!=null && !"".equals(projectUID.trim())) {
			countCriteria.add(Restrictions.eq("projectID", projectUID.trim()));
		}
		//所属小区
		if(communityUID!=null && !"".equals(communityUID.trim())) {
			countCriteria.add(Restrictions.eq("communityID", communityUID.trim()));
		}
		//权限资源匹配
		String authorityRes = iResourceAccessControlDao.queryAuthorityProjResSql();
		if(!"".equals(authorityRes)) {
			//这是一个直接与底层数据库耦合的查询，注意避免数模更改带来的系统问题
			countCriteria.add(Restrictions.sqlRestriction("{alias}.t_project_id in("+authorityRes+")"));
		}
		return ((Long)countCriteria.setProjection(Projections.rowCount()).list().get(0)).intValue();
	}
	
	/**
	 * 根据集中器UID级联删除关联信息
	 * 包括：分配表、温度点
	 * @param concentratorUID
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-5-8
	 */
	public ResponseMsg deleteCascadeByConcentratorUID(String concentratorUID) throws Exception {
		//删除集中器所属的分配表
		String delAssignMeterHql = "delete from IAssignMeter am " +
				"where am.concentratorID='"+concentratorUID+"'";
		this.runFormatHSql(delAssignMeterHql);
		//删除集中器所属的温度点
		String delTempPointHql = "delete from ITemperaturePoint tp " +
				"where tp.concentratorID='"+concentratorUID+"'";
		this.runFormatHSql(delTempPointHql);
		//删除集中器信息
		this.deleteEntityById(concentratorUID);
		return ResponseMsg.getInstance(true, "");
	}
	
	/**
	 * 统计相同集中器号的集中器数量，避免系统录入相同集中器号的集中器信息
	 * @param concentratorNo
	 * @param concentratorUID
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-7-23
	 */
	public int countByConcentratorNo(String concentratorNo, String concentratorUID) throws Exception {
		String hsql = "select count(*) from IConcentrator c " +
				"where trim(c.concentratorNo)='"+concentratorNo.trim()+"'";
		if(concentratorUID!=null && !"".equals(concentratorUID)) {
			hsql += " and c.id<>'"+concentratorUID+"'";
		}
		return ((Long)this.getCurrentSession().createQuery(hsql).uniqueResult()).intValue();
	}

	/**
	 * @return the iResourceAccessControlDao
	 */
	public IResourceAccessControlDao getiResourceAccessControlDao() {
		return iResourceAccessControlDao;
	}

	/**
	 * @param iResourceAccessControlDao the iResourceAccessControlDao to set
	 */
	public void setiResourceAccessControlDao(
			IResourceAccessControlDao iResourceAccessControlDao) {
		this.iResourceAccessControlDao = iResourceAccessControlDao;
	}
	
}
